package com.mc.lp.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.mc.lp.database.dao.IExtraAcademicRecordDAO;
import com.mc.lp.database.dao.IRecommendationDAO;
import com.mc.lp.database.entity.ExtraAcademicRecordEntity;
import com.mc.lp.database.entity.helper.ExtraAcademicRecordHelper;
import com.mc.lp.database.exception.ConcurrentAccessException;
import com.mc.lp.database.service.IAttachmentService;
import com.mc.lp.service.ExtraAcademicService;
import com.mc.lp.service.MicroCampusAbstractService;
import com.mc.lp.shared.util.constants.ResponseStatus;
import com.mc.lp.shared.vo.EntitySaveResponse;
import com.mc.lp.shared.vo.ExtraAcademicRecordVO;
import com.mc.lp.shared.vo.IValueObject;
import com.mc.lp.shared.vo.SearchCriteriaVO;
import com.mc.lp.shared.vo.ServiceResponse;
import com.mc.lp.shared.vo.StudentRecordVO;
import com.mc.lp.shared.vo.ValueObjectList;

/*
 * @author aphanda
 * @date Sep 21, 2014
 * @time 12:45:42 AM
 */
@Service
public class ExtraAcademicServiceImpl extends
MicroCampusAbstractService<ExtraAcademicServiceImpl> implements ExtraAcademicService {

	
	
	// DV I dont understand why you have changes <BUSINESS>DAO classes to <BUSINESS>Dao in application-aspects.xml file. 
	// Cant you change few of inconsistant "dao" beans with updated one "DAO".
	@Resource
	IExtraAcademicRecordDAO extraAcademicRecordDao;
	
	@Resource
	IAttachmentService attachmentService;
	
	@Resource
	IRecommendationDAO recommendationDAO;
	
	
	/*ExtraAcademicRecordHelper academicRecordHelper = new ExtraAcademicRecordHelper();
	*/
	
	@Transactional
	public IValueObject saveExtraAcademics(StudentRecordVO studentRecordVO) throws DataAccessException, ConcurrentAccessException {
		ArrayList<ExtraAcademicRecordVO> vos = new ArrayList<ExtraAcademicRecordVO>();
		ServiceResponse<ExtraAcademicRecordVO> extraAcademicRecords = new ServiceResponse<ExtraAcademicRecordVO>();
		ExtraAcademicRecordHelper helper = new ExtraAcademicRecordHelper();
			for (ExtraAcademicRecordVO vo : studentRecordVO.getExtraAcademics()) {
				EntitySaveResponse response = new EntitySaveResponse(vo.getSid(), "ExtraAcademics");
				
				ExtraAcademicRecordEntity dbRecord = new ExtraAcademicRecordEntity();
				ExtraAcademicRecordEntity academic = helper.getEntity(vo);
				academic.setStudentEntity(studentRecordVO.getSearchCriteria().getStudentEntityId());

				if (!vo.isNewRow()) {
					if (vo.getSid() != 0) {
						dbRecord = extraAcademicRecordDao.get(vo.getSid());
						// Delete the entity which is marked as deleted on UI
						if (vo.isRowDeleted()) {
								try {
									extraAcademicRecordDao.delete(dbRecord);
									response.setStatus(ResponseStatus.SUCCESS);
									extraAcademicRecords.setStatus(ResponseStatus.SUCCESS);
								} catch (DataAccessException e) {
									getLogger().error("saveExtraAcademics()", e);
									response.setStatus(ResponseStatus.FAILED);
									response.setMsg(e.getMessage());
									
									extraAcademicRecords.setStatus(ResponseStatus.FAILED);
									extraAcademicRecords.setMsg(e.getMessage());
									
								} catch (ConcurrentAccessException e) {
									getLogger().error("saveExtraAcademics()", e);
									response.setStatus(ResponseStatus.FAILED);
									response.setMsg(e.getMessage());
									extraAcademicRecords.setStatus(ResponseStatus.FAILED);
									extraAcademicRecords.setMsg(e.getMessage());
								}
							continue;
						}
						//AP this we need to do with reflection to avoid any kind or missed property situation.
						//if (!dbRecord.equals(academic)) {
							try {
								helper.setEntity(vo, dbRecord);
								extraAcademicRecordDao.saveOrUpdate(dbRecord);
								response.setStatus(ResponseStatus.SUCCESS);
								extraAcademicRecords.setStatus(ResponseStatus.SUCCESS);
							} catch (DataAccessException e) {
								getLogger().error("saveExtraAcademics()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								extraAcademicRecords.setStatus(ResponseStatus.FAILED);
								extraAcademicRecords.setMsg(e.getMessage());
							} catch (ConcurrentAccessException e) {
								getLogger().error("saveExtraAcademics()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								extraAcademicRecords.setStatus(ResponseStatus.FAILED);
								extraAcademicRecords.setMsg(e.getMessage());
							}
						//}
					}
				}else {
					extraAcademicRecordDao.save(academic);
					vo.setNewRow(false);
					response.setStatus(ResponseStatus.SUCCESS);
					extraAcademicRecords.setStatus(ResponseStatus.SUCCESS);
					//add response to list and send back to ui
				}
				vos.add(vo);
			}
			
			extraAcademicRecords.setResult(vos);
			return extraAcademicRecords;
	}

	@Transactional
	public IValueObject getExtraAcademicsRecordsByEntityIdGrade(StudentRecordVO studentRecordVO) {
		
		SearchCriteriaVO searchValue= studentRecordVO.getSearchCriteria();
		List<ExtraAcademicRecordVO> resultVoList = new ArrayList<ExtraAcademicRecordVO>();
		ServiceResponse<ExtraAcademicRecordVO> response = new ServiceResponse<ExtraAcademicRecordVO>();
		
		ExtraAcademicRecordHelper helper = new ExtraAcademicRecordHelper();
		
		Long entityId=searchValue.getStudentEntityId();
		int gradeId=searchValue.getGradeId();
		getLogger().info("getAcademicsRecordsByGradeAndTerm : entityId:"+entityId +", gradeId :"+gradeId);
		
		List<ExtraAcademicRecordEntity> searchedRecords=extraAcademicRecordDao.fetchDetailsByEntityIdGrade(entityId,gradeId);
		if(CollectionUtils.isEmpty(searchedRecords)){
			response.setStatus(ResponseStatus.NOT_FOUND);
			getLogger().info("getAcademicsRecordsByGradeAndTerm : No record found in db for given params");
		}else{
			getLogger().info("getAcademicsRecordsByGradeAndTerm : Total records found :"+ searchedRecords);
			for(ExtraAcademicRecordEntity entity: searchedRecords){
				ExtraAcademicRecordVO vo = helper.getVO(entity);
				resultVoList.add(vo);
			}
			//get attachments to be displayed on ui
			ValueObjectList fileList = attachmentService.getAttachmentsWithoutData(searchValue);
			
			//RecommendationVO vo = getRecommendations(searchValue);
			//response.setObject(vo);
			response.setExtraInfo(fileList);
			response.setStatus(ResponseStatus.SUCCESS);
		}
		response.setResult(resultVoList);
		return response;	
		
		
	}
	
	
	// DV BP-2 Please fix recommendation for ExtraAcademic page
	/*private RecommendationVO getRecommendations(SearchCriteriaVO searchvalue) {
		// TODO Auto-generated method stub
		RecommendationEntityHelper helper  = new RecommendationEntityHelper();
		
		return helper.getVO(recommendationDAO.fetchRecommendationByRecordType(searchvalue));

	}*/
	@Transactional
	public IValueObject getExtraAcademicsByEntityId(StudentRecordVO studentRecordVO) {
		return null;
	}

	
	
	@Transactional
	public List<ExtraAcademicRecordVO> getExtraAcademicsByGrades(Long studentEntity,
			List<Integer> gradeValueList) {
		List<ExtraAcademicRecordVO> voList = new ArrayList<ExtraAcademicRecordVO>();
		List<ExtraAcademicRecordEntity> extraAcadList = new ArrayList<ExtraAcademicRecordEntity>();

		ExtraAcademicRecordHelper helper = new ExtraAcademicRecordHelper();

		extraAcadList = extraAcademicRecordDao.fetchExtraAcademicsByGrades(studentEntity,  gradeValueList);
		for (ExtraAcademicRecordEntity entity : extraAcadList) {
			voList.add(helper.getVO(entity));
		}
		return voList;
}
	
	

	@Transactional
	public List<ExtraAcademicRecordVO> getExtraAcademicsByEntityIdGrade(Long entityId, int gradeId) {
		
		List<ExtraAcademicRecordVO> voList = new ArrayList<ExtraAcademicRecordVO>();
		List<ExtraAcademicRecordEntity> extraAcadList = new ArrayList<ExtraAcademicRecordEntity>();

		extraAcadList = extraAcademicRecordDao.fetchExtraAcademicsByGrades(entityId, new ArrayList<Integer>(Arrays.asList(gradeId)));
		for (ExtraAcademicRecordEntity entity : extraAcadList) {
			voList.add(new ExtraAcademicRecordHelper().getVO(entity));
		}
		return voList;
	}


}
